package com.platform.analysis.enums;

import com.platform.comm.constants.EnumOption;
import com.platform.comm.enums.IEnumOption;

import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author liujizheng
 * @version 1.0
 * @ClassName AggregatorFun
 * @Description 聚合函数
 * @date 2021/9/29 17:50
 */
@EnumOption(name = "aggregatorFun")
public enum AggregatorFun implements IEnumOption<String>, Function<String, String> {
    /**
     * 求和
     */
    SUM("求和", " SUM(%s) "),
    /**
     * 平均数
     */
    AVG("平均数", " AVG(%s) "),
    /**
     * 计数
     */
    COUNT("计数", " COUNT(%s) "),
    /**
     * 去重计数
     */
    COUNTD("去重计数", " COUNT(DISTINCT %s) "),
    /**
     * 最大值
     */
    MAX("最大值", " MAX(%s) "),
    /**
     * 最小值
     */
    MIN("最小值", " MIN(%s) "),
    /**
     * 整体标准差
     */
//    STDDEV_POP("整体标准差", " stddev_pop(%s) "),
    /**
     * 样本标准差
     */
//    STDDEV_SAMP("样本标准差", " stddev_samp(%s) "),
    /**
     * 整体方差
     */
//    VAR_POP("整体方差", " var_pop(%s) "),
    /**
     * 样本方差
     */
//    VAR_SAMP("样本方差", " var_samp(%s) ")
    ;

    String title;
    String operation;
    AggregatorFun(String title, String operation) {
        this.title = title;
        this.operation = operation;
    }

    /**
     * 枚举项 “键”
     *
     * @return key 键
     */
    @Override
    public String key() {
        return name();
    }

    /**
     * 枚举项 “值”
     *
     * @return value 值
     */
    @Override
    public String value() {
        return title;
    }

    /**
     * 枚举options
     *
     * @return 枚举项组成的map
     */
    @Override
    public Map<String, String> enums() {
        return Arrays.stream(values()).collect(Collectors.toMap(IEnumOption::key, IEnumOption::value));
    }

    public static AggregatorFun parse(String name) {
        Optional<String> optional = Arrays.stream(values()).map(AggregatorFun::name).filter(fun -> fun.equals(name)).findAny();
        return optional.isPresent() ? valueOf(name) : null;
    }

    /**
     * Applies this function to the given argument.
     *
     * @param s the function argument
     * @return the function result
     */
    @Override
    public String apply(String s) {
        return String.format(operation, s);
    }
}
